“熟肉”也能继续炒:一键完成视频字幕文件抽取、问答定位 您所在的位置:网站首页 jupyter 导入rarfile “熟肉”也能继续炒:一键完成视频字幕文件抽取、问答定位

“熟肉”也能继续炒:一键完成视频字幕文件抽取、问答定位

2023-03-20 15:15| 来源: 网络整理| 查看: 265

0 项目背景

什么是“熟肉”?经常追剧的朋友都知道,对于很多的美日韩剧、动漫资源都会标注一个生肉和熟肉的标签。

“熟肉”指的是加工过的视频。起因是早期的国外剧集流进国内都是外语版本,后期都是靠的各个字幕组进行翻译才有了字幕版。整个过程就像是肉类加工,将不能食用的生肉变成能够直接入口的成品。现在这两个词语更多被用于称呼视频的有字幕版本和无字幕版本。

但是,“熟肉”也分外挂字幕版本,以及内嵌字幕版本。本项目探讨的就是内嵌字幕视频的字幕文件抽取。因为在一些场景下,比如: - 我们对内嵌“熟肉”字幕有修改的需求,但是又不能直接编辑 - 需要制作翻译版字幕,但是时间轴要自己对齐;通过语音识别转写的方式,识别结果还需要根据原字幕重新矫正 - 后续要支持诸如渲染、检索、数据分析等诸多用途,特别是视频问答相关任务,但是文稿是生成了,却也是对不回去时间轴

总之,在视频字幕抽取的场景上,有时候还是需要引入时间轴信息,并在此基础上,合成常用的srt字幕格式文件。

本项目就针对这个需求,基于生成的字幕,帮助读者快速完成视频关键信息的定位。

具体来讲,我们经常会需要看一个比较冗长的视频,比如一门2小时的课程。但是有时候只是为了去找个问题答案,类似于老师在X分X秒时提到说XX工具如何使用。虽然可以通过手动拖进度条的方法来处理,但是耗时耗力,而且还比较容易遗漏。就算字幕可以快速批量提取,但是如果视频文件比较长,文字信息量也还是比较大的,查找信息需要经过这样的流程:视频提取字幕——在字幕中找关键信息——到视频中拖进度条翻查相关视频介绍。

显然,上面的流程不太智能:能不能直接发问,然后通过智能应用直接告诉我们,想找的答案从本视频的第X分X秒开始看就行?

接下来,我们就看看如何来实现这个流程。

关于视频字幕抽取、实时翻译等工作,前期平台上的几位大佬们已经写得非常到位了,这让本项目的开展更加顺利: - PaddleOCR系列软件:自动为英文视频生成中文字幕(看电影再也不用担心啦):该项目使用百度翻译API实现英文视频生成中文字幕,但是其实是通过图片拼接实现,没有考虑到时间轴 - 【PPISG】挑战最快字幕项目:秒级提取分钟视频,超精准还原OCR提取字幕:前一阵子平台视频字幕提取迭代的终极方案,又快又准,本项目将在此基础上,合入时间轴信息,生成srt字幕文件。

1 配置环境

在BML Codelab环境中已经预装了PaddleNLP\PaddleOCR,读者可以直接点击右侧【包管理】安装最新版本,然后点击【内核-重启内核】。

!pip list Package Version ------------------------------ --------------- absl-py 0.8.1 aiohttp 3.8.3 aiosignal 1.2.0 alembic 1.8.1 altair 4.2.0 anyio 3.6.1 argon2-cffi 21.3.0 argon2-cffi-bindings 21.2.0 aspy.yaml 1.3.0 astor 0.8.1 astroid 2.4.1 async-generator 1.10 async-timeout 4.0.2 asynctest 0.13.0 attrdict 2.0.1 attrs 22.1.0 audioread 2.1.8 autopep8 1.6.0 Babel 2.8.0 backcall 0.1.0 backports.zoneinfo 0.2.1 bce-python-sdk 0.8.53 beautifulsoup4 4.11.1 bleach 5.0.1 blinker 1.5 Bottleneck 1.3.7 braceexpand 0.1.7 cachetools 4.0.0 certifi 2019.9.11 certipy 0.1.3 cffi 1.15.1 cfgv 2.0.1 chardet 3.0.4 charset-normalizer 2.1.1 click 8.0.4 cloudpickle 1.6.0 cma 2.7.0 colorama 0.4.4 colorlog 4.1.0 commonmark 0.9.1 cryptography 38.0.1 cssselect 1.2.0 cssutils 2.6.0 cycler 0.10.0 Cython 0.29 datasets 2.7.0 debugpy 1.6.0 decorator 4.4.2 defusedxml 0.7.1 dill 0.3.4 Distance 0.1.3 easydict 1.9 editdistance 0.6.2 entrypoints 0.4 et-xmlfile 1.0.1 fastapi 0.93.0 fastjsonschema 2.16.1 filelock 3.0.12 fire 0.5.0 flake8 4.0.1 Flask 1.1.1 Flask-Babel 1.0.0 Flask-Cors 3.0.8 flatbuffers 23.3.3 fonttools 4.38.0 forbiddenfruit 0.1.3 frozenlist 1.3.0 fsspec 2022.11.0 funcsigs 1.0.2 future 0.18.0 g2p-en 2.1.0 g2pM 0.1.2.5 gast 0.3.3 gitdb 4.0.5 GitPython 3.1.14 google-auth 1.10.0 google-auth-oauthlib 0.4.1 graphviz 0.13 greenlet 1.1.3 grpcio 1.35.0 gunicorn 20.0.4 gym 0.12.1 h11 0.14.0 h5py 2.9.0 huggingface-hub 0.13.0 identify 1.4.10 idna 2.8 imageio 2.6.1 imageio-ffmpeg 0.3.0 imgaug 0.4.0 importlib-metadata 4.2.0 importlib-resources 5.9.0 inflect 6.0.2 ipykernel 6.9.1 ipython 7.34.0 ipython-genutils 0.2.0 ipywidgets 7.6.5 isort 4.3.21 itsdangerous 1.1.0 jdcal 1.4.1 jedi 0.17.2 jieba 0.42.1 Jinja2 3.0.0 joblib 0.14.1 JPype1 0.7.2 json5 0.9.5 jsonlines 3.1.0 jsonschema 4.16.0 jupyter-archive 3.2.1 jupyter_client 7.3.5 jupyter-core 4.11.1 jupyter-lsp 1.5.1 jupyter-server 1.16.0 jupyter-telemetry 0.1.0 jupyterhub 1.3.0 jupyterlab 3.4.5 jupyterlab-language-pack-zh-CN 3.4.post1 jupyterlab-pygments 0.2.2 jupyterlab-server 2.10.3 jupyterlab-widgets 3.0.3 kaldiio 2.17.2 kiwisolver 1.1.0 lazy-object-proxy 1.4.3 Levenshtein 0.20.9 librosa 0.8.1 lightgbm 3.1.1 llvmlite 0.31.0 lmdb 1.4.0 loguru 0.6.0 lxml 4.9.1 Mako 1.2.2 Markdown 3.1.1 MarkupSafe 2.0.1 matplotlib 2.2.3 matplotlib-inline 0.1.6 mccabe 0.6.1 mistune 0.8.4 mock 5.0.1 more-itertools 7.2.0 moviepy 1.0.1 multidict 6.0.2 multiprocess 0.70.12.2 nara-wpe 0.0.9 nbclassic 0.3.1 nbclient 0.5.13 nbconvert 6.4.4 nbformat 5.5.0 nest-asyncio 1.5.5 netifaces 0.10.9 networkx 2.4 nltk 3.4.5 nodeenv 1.3.4 notebook 5.7.0 numba 0.48.0 numpy 1.21.6 oauthlib 3.1.0 objgraph 3.4.1 onnxruntime 1.11.0 OpenCC 1.1.6 opencv-contrib-python 4.4.0.46 opencv-python 4.6.0.66 openpyxl 3.0.5 opt-einsum 3.3.0 packaging 21.3 paddle-bfloat 0.1.7 paddle2onnx 1.0.0 paddleaudio 1.1.0 paddlefsl 1.1.0 paddlehub 2.3.0 paddlenlp 2.5.2 paddleocr 2.5.0.2 paddlepaddle-gpu 2.4.0.post112 paddleslim 2.3.4 paddlespeech 1.3.0 paddlespeech-feat 0.1.0 pamela 1.0.0 pandas 1.1.5 pandocfilters 1.5.0 parameterized 0.8.1 parl 1.4.1 parso 0.7.1 pathlib 1.0.1 pathos 0.2.8 pattern-singleton 1.2.0 pdf2docx 0.5.6 pexpect 4.7.0 pickleshare 0.7.5 Pillow 9.4.0 pip 22.1.2 pkgutil_resolve_name 1.3.10 platformdirs 3.1.0 plotly 5.8.0 pluggy 1.0.0 pooch 1.7.0 portalocker 2.7.0 pox 0.3.2 ppft 1.7.6.6 praatio 5.0.0 pre-commit 1.21.0 premailer 3.10.0 prettytable 0.7.2 proglog 0.1.9 prometheus-client 0.14.1 prompt-toolkit 2.0.10 protobuf 3.20.0 psutil 5.7.2 ptyprocess 0.7.0 py4j 0.10.9.2 pyarrow 10.0.0 pyasn1 0.4.8 pyasn1-modules 0.2.7 pybboxes 0.1.1 pybind11 2.10.3 pyclipper 1.3.0.post4 pycodestyle 2.8.0 pycparser 2.21 pycryptodome 3.9.9 pydantic 1.10.6 pydeck 0.8.0 pydocstyle 5.0.2 pyflakes 2.4.0 pyglet 1.4.5 Pygments 2.13.0 pyhumps 3.8.0 pylint 2.5.2 Pympler 1.0.1 PyMuPDF 1.20.2 pynvml 8.0.4 pyOpenSSL 22.0.0 pyparsing 3.0.9 pypinyin 0.44.0 pypinyin-dict 0.5.0 pypmml 0.9.11 pyrsistent 0.18.1 python-dateutil 2.8.2 python-docx 0.8.11 python-json-logger 2.0.4 python-jsonrpc-server 0.3.4 python-language-server 0.33.0 python-Levenshtein 0.20.9 python-lsp-jsonrpc 1.0.0 python-lsp-server 1.5.0 pytz 2019.3 pytz-deprecation-shim 0.1.0.post0 PyWavelets 1.3.0 pyworld 0.2.12 PyYAML 5.1.2 pyzmq 23.2.1 rapidfuzz 2.13.7 rarfile 3.1 recordio 0.1.7 regex 2022.10.31 requests 2.24.0 requests-oauthlib 1.3.0 resampy 0.2.2 responses 0.18.0 rich 12.6.0 rope 0.17.0 rsa 4.0 ruamel.yaml 0.17.21 ruamel.yaml.clib 0.2.6 sacrebleu 2.3.1 sahi 0.10.1 scikit-image 0.19.3 scikit-learn 0.24.2 scipy 1.6.3 seaborn 0.10.0 semver 2.13.0 Send2Trash 1.8.0 sentencepiece 0.1.96 seqeval 1.2.2 setuptools 56.2.0 shapely 2.0.0 shellcheck-py 0.7.1.1 simplegeneric 0.8.1 six 1.16.0 sklearn 0.0 smmap 3.0.5 sniffio 1.3.0 snowballstemmer 2.0.0 SoundFile 0.10.3.post1 soupsieve 2.3.2.post1 SQLAlchemy 1.4.41 starlette 0.25.0 streamlit 1.13.0 streamlit-image-comparison 0.0.3 tabulate 0.9.0 tb-nightly 1.15.0a20190801 tb-paddle 0.3.6 tenacity 8.0.1 tensorboard 2.1.0 tensorboardX 1.8 termcolor 1.1.0 terminado 0.15.0 terminaltables 3.1.10 testpath 0.4.2 TextGrid 1.5 threadpoolctl 2.1.0 tifffile 2021.11.2 timer 0.2.2 tinycss2 1.1.1 toml 0.10.0 toolz 0.12.0 tornado 6.2 tqdm 4.64.1 traitlets 5.4.0 typed-ast 1.4.1 typeguard 2.13.3 typer 0.7.0 typing_extensions 4.5.0 tzdata 2022.7 tzlocal 4.2 ujson 1.35 urllib3 1.25.11 uvicorn 0.20.0 validators 0.20.0 virtualenv 16.7.9 visualdl 2.4.0 watchdog 2.2.0 wcwidth 0.1.7 webencodings 0.5.1 webrtcvad 2.0.10 websocket-client 1.4.1 websockets 10.4 Werkzeug 0.16.0 whatthepatch 1.0.2 wheel 0.36.2 widgetsnbextension 3.5.2 wrapt 1.12.1 xarray 0.16.2 xgboost 1.3.3 xlrd 1.2.0 xxhash 3.1.0 yacs 0.1.8 yapf 0.26.0 yarl 1.7.2 zhon 1.1.5 zipp 3.8.1 [1m[[0m[34;49mnotice[0m[1;39;49m][0m[39;49m A new release of pip available: [0m[31;49m22.1.2[0m[39;49m -> [0m[32;49m23.0.1[0m [1m[[0m[34;49mnotice[0m[1;39;49m][0m[39;49m To update, run: [0m[32;49mpip install --upgrade pip[0m !pip install -U scikit-image # pip 安装PaddleSpeech !pip install paddlespeech !pip install moviepy # 下载nltk数据包,放入到nltk可以检索的路径下 %cd /home/aistudio !wget -P data https://paddlespeech.bj.bcebos.com/Parakeet/tools/nltk_data.tar.gz !tar zxvf data/nltk_data.tar.gz2 导入环境import os import cv2 from PIL import Image import numpy as np from tqdm import tqdm from paddleocr import PaddleOCR, draw_ocr3 导入模型ocr = PaddleOCR(use_angle_cls=False, lang="ch")

为减少干扰,进一步提高识别效果和速度,对于字幕固定在下方的视频,我们最好通过抠图,把会出现字幕的部分裁剪出来,然后用这些数据预测。

4 视频字幕文稿的提取

这里,我们不仅需要提取字幕,还需要恢复整段文稿的标点,从而为后面开展视频问答做好准备。

src_video = cv2.VideoCapture('Trim.mp4') fps = int(src_video.get(cv2.CAP_PROP_FPS)) total_frame = int(src_video.get(cv2.CAP_PROP_FRAME_COUNT)) # 计算视频总帧数 save_text = [] last_res = 'None' for i in tqdm(range(total_frame)): success, frame = src_video.read() if i % (fps) == 0: if success: result = ocr.ocr(frame[-120:-30,:], cls=True) if len(result)> 0: res = result[0][1][0] if ((res[:-1] not in last_res) and (last_res[:-1] not in res)): save_text.append(res) last_res = res finally_text = [] for save in save_text: if not any(save[:-1] in text for text in finally_text): finally_text.append(save) # 把字幕识别结果全部拼起来 input_text = '' for index in finally_text: input_text += index

标点恢复能力使用了PaddleSpeech Python API提供的一键预测功能。

from paddlespeech.cli.text.infer import TextExecutor text_punc = TextExecutor() result = text_punc(text=input_text)

应该说,标点恢复结果可能未必能让我们100%满意,但是对于支撑后面的问答功能,应该是完全够用的。

print(result) 让我们从一次时光旅行,开启植物天堂的故事!地球的午夜,是在火山喷发中度过的,到了凌晨三、四点,在海洋深处,有了生命的迹象,清晨6点多,更加壮丽的生命乐章开始了,一种蓝藻细菌,学会利用二氧化碳、水和阳光,制造生命所需能量,同时释放出了氧气,这个被称为光合作用的过程,为植物世界打开了大门,此时,中国的陆地也逐渐从海洋露出,形成岛吗?但在相当长的时间里,陆地十分荒凉,没有生机,这些岩石坚硬,无法储存水分,是当时陆地环境的写照,直到晚上九点多,也就是四亿年前左右,些矮小的生命开始征服陆地,她们用一种近似于根的构造,固定在岩石上。5 SRT格式字幕文件的生成5.1 关于SRT字幕

视频文件中最简单、最常见的外挂字幕格式是SRT(SubRip Text)。SRT字幕通常以srt作为后缀,作为外挂字幕,多数主流播放器都支持直接加载并显示SRT字幕。该格式是基于纯文本的格式,使用CR+LF作为换行符(Windows下常用换行符,*nix使用LF作为换行符)。每个SRT文件包含至少一个字幕段。每个字幕段有四部分构成:

字幕序号字幕显示的起始时间字幕内容(可多行)空白行(表示本字幕段的结束)

其中字幕序号一般是顺序增加的,表示字幕是一系列连续的序列。但该数值在字幕显示中不起任何作用,只是起着标记和标识的作用,方便分配翻译行数用。字幕序号的值可以随意,1和100都一样,并不会影响字幕的显示。但字幕序号也是字幕段的一部分,所以不能没有或者删去,否则在播放时,将出现错误。

字幕显示起始时间的格式如下:hour:minute:second.millisecond --> hour:minute:second.millisecond 或hour:minute:second,millisecond --> hour:minute:second,millisecond后面还可以附加用于指定字幕显示位置的信息,以像素为单位,格式如下: X1:number Y1:number X2:number Y2:number。 一个典型的SRT文件如下(截取自阿凡达中英字幕):

3 00:00:39,770 --> 00:00:41,880 在经历了一场人生巨变之后 When I was lying there in the VA hospital ... 4 00:00:42,550 --> 00:00:44,690 我被送进了退伍军人管理局医院 ... with a big hole blown through the middle of my life, 5 00:00:45,590 --> 00:00:48,120 那段时间我经常会梦到自己在飞翔 ... I started having these dreams of flying. 6 00:00:49,740 --> 00:00:51,520 终获自由 I was free. 7 00:00:54,620 --> 00:00:55,830 而不幸的是 Sooner or later though, ... 参考资料:SRT字幕格式5.2 代码改造分析

针对SRT格式字幕的特点,我们结合前面的字幕提取代码,至少有下面几个改造要点: - 增加序号:其实这个相对好办,因为我们现在有做句子去重操作,去重时顺便给每个提取语句加上序号不太难 - 将视频帧与时间对上,换算成hour:minute:second.millisecond格式:帧率和时间要有个转化 - 定位每段文本的开始和结束时间:这是本项目的重中之重

具体到视频帧与时间轴的对应问题,其实也不会太难处理,因为我们通常所说的视频帧率,有这样一个大的定义——FPS:每秒传输帧数(Frames Per Second)

为保证整个处理链路的一致性,使用OPENCV库获取帧率。其实前面的字幕提取代码已经用到了。

print(int(src_video.get(cv2.CAP_PROP_FPS))) 30

所以,我们测试的视频帧率为30,即每前进一帧,视频时间轴应当推进1/30 s。

5.3 代码实现5.3.1 字幕时间格式准备

我们首先需要格式化输出时间,因为字幕格式中,时间包含了毫秒。具体做法其实还是要用上拼接的方法。

from datetime import timedelta import math # 这里需要是整数秒 sec = 1 print('Time in Seconds:', sec) td = timedelta(seconds=sec) data_secs = math.modf(sec)[0] * 1000 print('Time in hh:mm:ss:', td) # Use the below code if you want it in a string print(str("%s,%03d" % (td, data_secs))) Time in Seconds: 1 Time in hh:mm:ss: 0:00:01 0:00:01,0005.3.2 字幕文件生成src_video = cv2.VideoCapture('Trim.mp4') # 获取视频帧率 fps = int(src_video.get(cv2.CAP_PROP_FPS)) # 计算视频总帧数 total_frame = int(src_video.get(cv2.CAP_PROP_FRAME_COUNT)) # 设置字幕序号 num = 0 # 设置字幕起始时间flag start_time = 0 end_time = 0 # 设置计时器 time_cost = 0 # # 设置字幕flag # text_flag = False save_text = [] save_time = [] last_res = 'None' with open('Trim.srt', 'w+') as f: for i in tqdm(range(total_frame)): success, frame = src_video.read() # 在视频字幕提取任务中,为了提速改为了每秒抽一帧,因此所有时间都是整数 # if not firstlaunch: if i % (fps) == 0: if success: result = ocr.ocr(frame[-120:-30,:], cls=True) if len(result)> 0: res = result[0][1][0] if ((res[:-1] not in last_res) and (last_res[:-1] not in res)): # 检测到新字幕,录入并开始计时 last_res = res # 更新序号 num += 1 # 更新开始时间 td = timedelta(seconds=i) data_secs = math.modf(i)[0] * 1000 start_time = "%s,%03d" % (timedelta(seconds=i/fps), 0 * 1000) # 一段语句的结束时间,和语速也有一定关系,读者可以自行调整 end_time = "%s,%03d" % (timedelta(seconds=i/fps), 1.5 * 1000) f.write(str(num) + '\n') f.write(start_time + ' --> ' + end_time + '\n') f.write(res + '\n') f.write('\n') # 保存文稿信息,用于后续标点恢复和问答任务 save_text.append(res) # 保存字幕 + 时间信息,用于快速截取视频片段 save_time.append(res + ' ' + str(i/fps)) # 整篇文章提取 finally_text = [] for save in save_text: if not any(save[:-1] in text for text in finally_text): finally_text.append(save) # 整篇文章提取,为了定位字幕时间 time_text = [] for save in save_time: if not any(save[:-1] in text for text in time_text): time_text.append(save)

我们把原视频文件和生成的字幕文件导入视频编辑器中,可以看到基本能够实时同步。

6 关键信息定位# 把字幕识别结果全部拼起来 input_text = '' for index in finally_text: input_text += index from paddlespeech.cli.text.infer import TextExecutor text_punc = TextExecutor() result = text_punc(text=input_text) # 保存读取的字幕文件 with open('article.txt','w') as f: f.writelines(result) f.close()

现在,我们向短视频输入问题,测试信息抽取的结果。

from pprint import pprint from paddlenlp import Taskflow schema = ['地球的午夜,是怎么度过的'] # Define the schema for entity extraction ie = Taskflow('information_extraction', schema=schema) pprint(ie(result)) [{'地球的午夜,是怎么度过的': [{'end': 34, 'probability': 0.4815907229682068, 'start': 29, 'text': '火山喷发中'}]}]

显然,我们得到了问题的答案。接下来是一个纯逻辑上的操作,要让信息抽取任务生成的问答结果在视频字幕中可以定位匹配。一般来讲,对于信息抽取任务,问题未必能完全在字幕中匹配到位(因为由用户数据,可操作性不强),但是答案基本是原文中来的。总的来说,后面我们要做对应文本信息所在的时间轴定位,通过让用户手动设置关键词可能会比较合理。

# 保存读取的字幕文件,带时间标记 with open('output.txt','w') as f: for i in save_time: f.writelines(i+'\n') f.close() def get_info(cell_text): # 将整理后的抽取结果返回为字典 schema_dict = {} # 抽取信息 a = ie(cell_text) for i in schema: if i in a[0]: schema_dict[i] = a[0][i][0]['text'] # 查看抽取信息 # print(a[0][i][0]['text']) else: schema_dict[i] = '' return schema_dict get_info(result)['地球的午夜,是怎么度过的'] '火山喷发中' with open('output.txt', encoding='utf-8') as file_obj: lines = file_obj.readlines() for line in lines: if '地球的午夜' in line: print('关键词定位时间:', line, "时间轴位置: %s,%03d" % (timedelta(seconds=float(line.split(' ')[1])), 0 * 1000)) # 输出的是按照计时得到的累计播放时间位置(非时间轴格式,按seconds计算) start = float(line.split(' ')[1]) if get_info(result)['地球的午夜,是怎么度过的'] in line: print('答案定位时间:', line, "时间轴位置: %s,%03d" % (timedelta(seconds=float(line.split(' ')[1])), 0 * 1000)) # 输出的是按照计时得到的累计播放时间位置(非时间轴格式,按seconds计算) end = float(line.split(' ')[1]) 关键词定位时间: 地球的午夜 8.0 时间轴位置: 0:00:08,000 答案定位时间: 是在火山喷发中度过的 9.0 时间轴位置: 0:00:09,000

显然,我们会需要裁剪的视频时间更长一些,这样能够尽可能减少上下文的丢失。于是在逻辑上,可以在定位的时间范围向前后各放大2秒。

from moviepy.editor import * import time clip = VideoFileClip('Trim.mp4').subclip(start-2, end + 2) new_file = str('answer.mp4') clip.write_videofile(new_file) Moviepy - Building video answer.mp4. MoviePy - Writing audio in answerTEMP_MPY_wvf_snd.mp3 MoviePy - Done. Moviepy - Writing video answer.mp4 Moviepy - Done ! Moviepy - video ready answer.mp4 from IPython.display import Video # 显示要进行问答的视频 Video('answer.mp4')

Your browser does not support the video element.

7 小结

在本项目中,我们在原有视频字幕极速提取项目的基础上,成功实现SRT格式字幕文件的一键生成。在此基础上,完成了一个视频问答答案的智能定位和剪辑。

当然,目前这个项目还有一些优化空间,比如,srt格式字幕中,结束时间是根据语速设定的,而不是通过字幕文本变化的比对实现。我们目前的方法速度会更快一些,但是也丢失了一些精度。

后续,将探索进一步优化的具体方法,欢迎感兴趣的读者一起参与交流。

本文章为转载 原项目链接



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有